using AlohaIM.Interfaces;
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace AlohaIM.Protocols {
	
	class Irc : IProtocol {
		string name = "IRC";
		string version = "0.1";
		string author = "Michael 'LeChuck' Borgmann";
		string description = "IRC protocol for Aloha IM";
		
		string host = "irc.mindforge.org";
		int port = 6667;
		
		byte[] buffer;
		
		Socket client;
		IPEndPoint server;
		
		// Constructor
		public Irc() {buffer = new byte[512];}
		
		// Implement Plugin Interface
		public string pluginName {get {return name;}}
		public string pluginVersion {get {return version;}}
		public string pluginAuthor {get {return author;}}
		public string pluginDescription {get {return description;}}
		
		// Implement Connection Interface
		
		// Establish Connection
		public bool connectionEstablish() {
			// Resolver obsolete for .NET 2.0
			IPHostEntry ip = Dns.GetHostByName(host);
			server = new IPEndPoint(ip.AddressList[0], port);
			
			// Specify Socket Type: IP4, I/O, TCP
			client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			
			// Begin to establish a connection
			IAsyncResult connection = 
			client.BeginConnect(server, new AsyncCallback(Connecting), client);
			
			// connection complete
			complete(connection);
			return true;
		}
		
		// Delegate of Establish Connection
		private void Connecting(IAsyncResult connection) {
			// complete connection
			client.EndConnect(connection);
			
			// Output
			if (client.Connected == false)
				System.Console.WriteLine("Connection not established");
			else
				Console.WriteLine("Connection established");
		}
		
		// Release Connection
		public bool connectionRelease() {return false;}
		
		// Implement Message Interface
		
		// Send Message
		public void messageSend(string message) {	
			// start sending a text message
			IAsyncResult packet =
			client.BeginSend(System.Text.Encoding.ASCII.GetBytes(message),
							 0,
							 message.Length,
							 SocketFlags.None,
							 new AsyncCallback(Sending),
							 null);
			
			// packet complete
			complete(packet);
		}
		
		// Delegate of Send Message
		private void Sending(IAsyncResult packet) {
			// complete sending
			client.EndSend(packet);
		}
		
		// Receive Message
		public void messageReceive() {
			// start receiving of text messages
			IAsyncResult packet =
			client.BeginReceive(buffer,
								0,
								buffer.Length,
								SocketFlags.None,
								new AsyncCallback(Receiving),
								null);

			// packet complete
			complete(packet);
		}
		
		// Delegate of Receive Message
		private void Receiving(IAsyncResult packet) {
			// complete receiving
			int bytes = client.EndReceive(packet);
			
			// output packet
			Console.WriteLine(System.Text.Encoding.ASCII.GetString(buffer, 0, bytes));
		}
		
		// Helper Checks for Completition 
		private static bool complete(IAsyncResult ar) {
			int i = 0;
			while (ar.IsCompleted == false) {
				if (i++ > 20) return false;
				Thread.Sleep(100);
			}
			return true;
		}
	}	
}
